package cn.net.isir.common.pay.alipay;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.*;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import cn.net.isir.utils.StringUtils;

/**
 * @author liuxubo
 * @filename AlipayAPI.java
 * @package cn.net.isir.common.pay.alipay
 * @email lxb@isir.net.cn
 * @date 2018/11/14
 * @comment 支付宝用到的API列表
 * @since 1.8
 */
public class AlipayAPI {
    // 声明log4j日志
    private static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(AlipayAPI.class);
    /**
     * 获取业务SDK
     */
    private static AlipayClient alipayClient = AlipayClientUtils.getAlipayClient();

    /**
     * 获取用于支付的sdk
     */
    private static AlipayClient alipayPayClient = AlipayClientUtils.getAlipayPayClient();

    /**
     * alipay.system.oauth.token(换取授权访问令牌)
     * <p><b>换取授权访问令牌</b></p>
     * <p>https://docs.open.alipay.com/api_9/alipay.system.oauth.token</p>
     *
     * @param grantType    值为authorization_code时，代表用code换取；值为refresh_token时，代表用refresh_token换取
     * @param code         授权码，用户对应用授权后得到。
     * @param refreshToken 刷刷新令牌，上次换取访问令牌时得到。见出参的refresh_token字段
     */
    public static AlipaySystemOauthTokenResponse alipaySystemOauthToken(String grantType, String code, String refreshToken) {
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        if (StringUtils.isNotBlank(grantType)) {
            request.setGrantType(grantType);//"authorization_code"
        }
        if (StringUtils.isNotBlank(code)) {
            request.setCode(code);//"4b203fe6c11548bcabd8da5bb087a83b"
        }
        if (StringUtils.isNotBlank(refreshToken)) {
            request.setRefreshToken(refreshToken);//"201208134b203fe6c11548bcabd8da5bb087a83b"
        }
        AlipaySystemOauthTokenResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return (AlipaySystemOauthTokenResponse) getResponse(response);
    }

    /**
     * alipay.user.info.share(支付宝会员授权信息查询接口)
     * <p><b>配合支付宝会员授权接口，根据授权token，查询授权信息。</b></p>
     * <p>https://docs.open.alipay.com/api_2/alipay.user.info.share</p>
     *
     * @param accessToken alipaySystemOauthToken接口中返回的accessToken
     */
    public static AlipayUserInfoShareResponse alipayUserInfoShare(String accessToken) {
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
        AlipayUserInfoShareResponse response = null;
        try {
            if (StringUtils.isNotBlank(accessToken)) {
                response = alipayClient.execute(request, accessToken);
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return (AlipayUserInfoShareResponse) getResponse(response);
    }

    /**
     * alipay.open.auth.token.app(换取应用授权令牌)
     * <p><b>换取应用授权令牌。在应用授权的场景下，商户把名下应用授权给ISV后，支付宝会给ISV颁发应用授权码app_auth_code，ISV可通过获取到的app_auth_code换取app_auth_token。app_auth_code作为换取app_auth_token的票据，每次用户授权带上的app_auth_code将不一样，app_auth_code只能使用一次，一天（从当前时间算起的24小时）未被使用自动过期。 刷新应用授权令牌，ISV可通过获取到的refresh_token刷新app_auth_token，刷新后老的refresh_token会在一段时间后失效（失效时间为接口返回的re_expires_in）。</b></p>
     * <p>https://docs.open.alipay.com/api_9/alipay.open.auth.token.app</p>
     *
     * @param grantType    authorization_code表示换取app_auth_token。 refresh_token表示刷新app_auth_token。
     * @param code         授权码，如果grant_type的值为authorization_code。该值必须填写
     * @param refreshToken 刷新令牌，如果grant_type值为refresh_token。该值不能为空。该值来源于此接口的返回值app_refresh_token（至少需要通过grant_type=authorization_code调用此接口一次才能获取）
     * @return AlipayOpenAuthTokenAppResponse
     */
    public static AlipayOpenAuthTokenAppResponse alipayOpenAuthTokenApp(String grantType, String code, String refreshToken) {
        AlipayOpenAuthTokenAppRequest request = new AlipayOpenAuthTokenAppRequest();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("grant_type", grantType);
        jsonObject.put("code", code);
        jsonObject.put("refresh_token", refreshToken);
        request.setBizContent(jsonObject.toJSONString());
        AlipayOpenAuthTokenAppResponse response = null;
        try {
            response = alipayPayClient.execute(request);
            logger.info("获取token成功，获取的token是：" + response.getAppAuthToken());
        } catch (AlipayApiException e) {
            e.printStackTrace();
            logger.error("支付宝换取应用授权令牌错误，异常信息", e);
        }
        return (AlipayOpenAuthTokenAppResponse) getResponse(response);
    }

    /**
     * alipay.open.agent.create(开启代商户签约、创建应用事务)
     * <p><b>在 ISV 代商户进行应用创建、产品签约时，用于开启一个操作事务，必须是第一个调用的接口</b></p>
     * <p>https://docs.open.alipay.com/api_50/alipay.open.agent.create</p>
     *
     * @param account        isv代操作的商户账号，可以是支付宝账号，也可以是pid（2088开头）
     *                       <p><b>contact_info   商户联系人信息，包含联系人名称、手机、邮箱信息。联系人信息将用于接受签约后的重要通知，如确认协议、到期提醒等。</b></p>
     * @param contact_name   联系人名称
     * @param contact_mobile 联系人手机号码
     * @param contact_email  联系人邮箱
     * @param order_ticket   订单授权凭证，填写都则对应事务提交进入预授权模式
     */
    public static AlipayOpenAgentCreateResponse alipayOpenAgentCreate(String app_auth_token,
                                                                      String account,
                                                                      String contact_name,
                                                                      String contact_mobile,
                                                                      String contact_email,
                                                                      String order_ticket) {
        AlipayOpenAgentCreateRequest request = new AlipayOpenAgentCreateRequest();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("account", account);
        jsonObject.put("order_ticket", order_ticket);
        JSONObject subJsonObject = new JSONObject();
        subJsonObject.put("contact_name", contact_name);
        subJsonObject.put("contact_mobile", contact_mobile);
        subJsonObject.put("contact_email", contact_email);
        jsonObject.put("contact_info", subJsonObject.toJSONString());
        request.setBizContent(jsonObject.toJSONString());
        logger.info(subJsonObject.toJSONString());
        logger.info(jsonObject.toJSONString());
        AlipayOpenAgentCreateResponse response = null;
        try {
//            request.putOtherTextParam("app_auth_token", app_auth_token);
            response = alipayPayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return (AlipayOpenAgentCreateResponse) getResponse(response);
    }

    /**
     * alipay.open.agent.confirm(提交代商户签约、创建应用事务)
     * <p><b>提交事务。只允许提交init状态的事务，submit|cancel|timeout 状态的都是终态，不允许提交，且不允许提交空事务，
     * 需要先调用代创建小程序、代签约当面付等业务接口，再提交事务。</b></p>
     * <p>https://docs.open.alipay.com/api_50/alipay.open.agent.confirm/</p>
     *
     * @param batch_no ISV 代商户操作事务编号，通过事务开启接口alipay.open.agent.create调用返回。
     */
    public static AlipayOpenAgentConfirmResponse alipayOpenAgentConfirm(String batch_no) {
        AlipayOpenAgentConfirmRequest request = new AlipayOpenAgentConfirmRequest();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("batch_no", batch_no);
        request.setBizContent(jsonObject.toJSONString());
        AlipayOpenAgentConfirmResponse response = null;
        try {
//            request.putOtherTextParam("app_auth_token", app_auth_token);
            response = alipayPayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return (AlipayOpenAgentConfirmResponse) getResponse(response);
    }

    /**
     * alipay.open.agent.cancel(取消代商户签约、创建应用事务)
     * <p><b>取消代商户签约、创建应用事务</b></p>
     * <p>https://docs.open.alipay.com/api_50/alipay.open.agent.cancel/</p>
     *
     * @param batch_no ISV 代商户操作事务编号，通过事务开启接口alipay.open.agent.create调用返回。
     */
    public static AlipayOpenAgentCancelResponse alipayOpenAgentCancel(String batch_no) {
        AlipayOpenAgentCancelRequest request = new AlipayOpenAgentCancelRequest();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("batch_no", batch_no);
        request.setBizContent(jsonObject.toJSONString());
        AlipayOpenAgentCancelResponse response = null;
        try {
//            request.putOtherTextParam("app_auth_token", app_auth_token);
            response = alipayPayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return (AlipayOpenAgentCancelResponse) getResponse(response);
    }

    /**
     * alipay.open.agent.order.query(查询申请单状态)
     * <p><b>代签约产品提交后，查询对应申请单的情况</b></p>
     * <p>https://docs.open.alipay.com/api_50/alipay.open.agent.order.query/</p>
     *
     * @param batch_no ISV 代商户操作事务编号，通过事务开启接口alipay.open.agent.create调用返回。
     * @return 参数列表：
     * order_status    String	必填	32	支付宝商户入驻申请单状态，申请单状态包括：
     * MERCHANT_INFO_HOLD=暂存，提交事务出现业务校验异常时，会暂存申请单信息，可以调用业务接口修正参数，并重新提交
     * MERCHANT_AUDITING=审核中，申请信息正在人工审核中
     * MERCHANT_CONFIRM=待商户确认，申请信息审核通过，等待联系人确认签约或授权
     * MERCHANT_CONFIRM_SUCCESS=商户确认成功，商户同意签约或授权
     * MERCHANT_CONFIRM_TIME_OUT=商户超时未确认，如果商户受到确认信息15天内未确认，则需要重新提交申请信息
     * MERCHANT_APPLY_ORDER_CANCELED=审核失败或商户拒绝，申请信息审核被驳回，或者商户选择拒绝签约或授权	MERCHANT_INFO_HOLD
     * confirm_url	String	选填	256	只有申请单状态在MERCHANT_CONFIRM状态下，才会返回商户确认签约链接	https://openhome.alipay.com/isv/settling/confirm.htm?orderNo=20180627015000000000009202531926
     * agent_app_id	String	选填	32	代理创建的应用ID，如果有代理商户创建应用，商户确认成功后，才返回应用ID，否则不返回。	2017111108241348
     * reject_reason	String	选填	128	审核失败的拒绝原因，只有审核失败才会返回该值	图片涉黄
     * merchant_pid	String	必填	32	商户pid	390284792319804
     */
    public static AlipayOpenAgentOrderQueryResponse alipayOpenAgentOrderQuery(String batch_no) {
        AlipayOpenAgentOrderQueryRequest request = new AlipayOpenAgentOrderQueryRequest();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("batch_no", batch_no);
        request.setBizContent(jsonObject.toJSONString());
        AlipayOpenAgentOrderQueryResponse response = null;
        try {
            response = alipayPayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return (AlipayOpenAgentOrderQueryResponse) getResponse(response);
    }

    /**
     * alipay.open.app.mini.templatemessage.send(小程序发送模板消息)
     * <p><b>小程序通过openapi给用户触达消息，主要为支付后的触达（通过消费id）和用户提交表单后的触达（通过formId）。</p></b>
     * <p>https://docs.open.alipay.com/api_5/alipay.open.app.mini.templatemessage.send</p>
     *
     * @param to_user_id       发送消息的支付宝账号
     * @param form_id          用户发生的交易行为的交易号，或者用户在小程序产生表单提交的表单号，用于信息发送的校验
     * @param user_template_id 用户申请的模板id号，固定的模板id会发送固定的消息
     * @param page             小程序的跳转页面，用于消息中心用户点击之后详细跳转的小程序页面
     * @param data             开发者需要发送模板消息中的自定义部分来替换模板的占位符({"keyword1": {"value" : "12:00"},"keyword2": {"value" : "20180808"},"keyword3": {"value" : "支付宝"}})
     */
    public static AlipayOpenAppMiniTemplatemessageSendResponse alipayOpenAppMiniTemplatemessageSend(String to_user_id,
                                                                                                    String form_id,
                                                                                                    String user_template_id,
                                                                                                    String page,
                                                                                                    JSONObject data) {
        AlipayOpenAppMiniTemplatemessageSendRequest request = new AlipayOpenAppMiniTemplatemessageSendRequest();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("to_user_id", to_user_id);
        jsonObject.put("form_id", form_id);
        jsonObject.put("user_template_id", user_template_id);
//        jsonObject.put("page", page);
        jsonObject.put("data", data);
        logger.info(jsonObject.toJSONString());
        request.setBizContent(jsonObject.toJSONString());
        AlipayOpenAppMiniTemplatemessageSendResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return (AlipayOpenAppMiniTemplatemessageSendResponse) getResponse(response);

    }

    /**
     * 公共判断方法
     *
     * @param response 返回
     * @return 返回response或者null
     */
    private static AlipayResponse getResponse(AlipayResponse response) {
        if (response == null) {
            return null;
        }
        if (response.isSuccess()) {
            logger.info("调用成功");
        } else {
            logger.info("调用失败");
        }
        return response;
    }

    public static void main(String[] args) {
        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipay.com/gateway.do",
                "2018110862114130",
                "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCOy7qQINT7h1xa14PFXhGNwreRZRRDYCI8rcRNRNSOKW1geEEJ/PZr1dBrTEhYzpfEiLQaaIsIzSMopCy0PrVZIy8xZRzcJ5tcd8fjuf8DqhtlILr/YMtfNEmvy4m0udB/65NQVsXGdLnly13Kdl/DF46FWvCeHpL0nAvtkTYmMFFBQEiJWe4WYde6C+t8VeRe5uvIqSiem+FFdH/mr5CkctSfD51idfkWbOOVAR9Xus4vMO3HgRJqzBC3a5OWj8UhQcpfURQoufo6aQZQLEwrUivkNJaqH2UWgps/4ZhkR3CfD4e6dwKeouwNqdjgBUkHo4L0ARwM8ektxCgh8tH9AgMBAAECggEAbl0PSC3X7r9jpeJDudtGfeYssncI/jnivDshKQc1sNpb6t+GhQ259wY+G2/NyrWBnyh46qA6NQc3UUXyNyzwRIBpDSg08gK6lPEO0PcEHfTvT23ImXBaPq7O9Mu/Fqs2dmfAZ6tpGEVHGE/hoYVz5fji8jajGdJPijbBEU/WJhSxL9XkD93rrN+cSaeuCamUqvYoXF9rJeI31ADbbYzf/IHBMcuJ/fbExHcANHW7lT9YZACTnyGgcCp0QfpBdybu0nOW5ghByKvQ07II0rezw/1pMpmo45ftkGKq4bcWph81+MiABeagY9h0ebbcpZ5qrY5/ms+Rws22/Bd+g9skEQKBgQDRg0Ubam5GKm5lmck/m9qU+8++qjYXreTgqw1UaTHIg4FUggjzVRCfVvUJ5xzF6lSzTPuvE+6yZqfsI7JBfTq9Z2TEfRUB72BXGBi0U324UYI6sk+a0ToB/x38NPNP62hDuiNq2HN56aaMb4gt9qmexYQIM3bnyTdQgHyZOU1ERwKBgQCues6J/Gax9IGPorJZJQmPnJywSkzHXcZ6vUCpGkSPx1XoFqd3ZxeVpyYnDNF8uvRMekp5WcOqLlae/CtS3CzziwexZCtp8C3SHo8rnNAvUPtcZv0LOb+jIqHXFJ/sLaMh2ypgDLzi65DXSaaO46Q9iOUCA2ZMBuuxZHKV8oYtmwKBgQC5h6hD3dznL53xRNztAiPvOIpAClS6ZVhAB9lW/YyDRsjZQAmTCaodoBCAA3P8Y0U8PhjGcj03KCbdusKYsb+5h/y47xcSTpsepQ0Dasfy1+Md/Vb2/v6CVBuGgpFQHWOITiYc8K5ZsCm3RPDv2vVbzwbbiE9sdEgSdqVfvlmI8wKBgGR90stilftUqfKCcFornNAcEZrvkD0bY595tO4wdOCinHXp5lY9CDZnaPAAz/8Y5m/N12sBKlKwEa/L6V/18+XpY2rmGKMRdDKa6zbhQH6gE8Xqgz+d6SQaZEAuXtV2i4iKZGOhsoC30FpOzyFpN0VBvTRlpNuQ+NrY0a5PWryVAoGBAJOT9yrW+a0BtK2vXaBMnDkyNcQGFGM4oanDQS7vCQ7udtIANQlHWxxO0UojaouoN6VAv1zjfWACosR0rGhxByEN3WN7fZKILZJpLWVyXcNe9QKgV2Ef0P8o7tuXCEUZbylxggsr5WmXE+skdw3IJ78rDVr/6Hz90kZEc4ayhE/b",
                "json",
                "UTF-8",
                "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4LwVChEscFkk7UcvyQuUjd58X0yenct2FHnJtc/l6xYMXqkWBmfglvAUETa9iuy4t0u1P0ZdsnuSFyVQcJeg6ZBDcxrn+BlSLiQvcWBvcVgY41dij0X7lOSD+hkOVeRBJHNwUpHyDgiL2MOklRjKmc6PxwSz5+vgefA4fhYs5fY0NncOzEhGxpP+SL10tvZn+jmwxT042v3Ly6+GBF2Bu7UnsZP5+AsD4EIebEFAekLzjKWWfAfB9s188JYGyIW5/eCOqXrXfbaDQ3Zz1+9uutIiklsWIFYOTASpACOv1PwAb2g0TXmNekJobHK8Yt024vesXbB27/mKLklLDOwJUwIDAQAB",
                "RSA2");
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setGrantType("authorization_code");
        request.setCode("570cf616974949a48c59d3695768WD69");
//        request.setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b");
        try {
            AlipaySystemOauthTokenResponse response = null;
            response = alipayClient.execute(request);
            if (response.isSuccess()) {
                logger.info("调用成功");
            } else {
                logger.info("调用失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
    }

    public static void main2(String[] args) {
        AlipayClient alipayClient = null;//
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setGrantType("authorization_code");
        request.setCode("9b382ba3a1074f4d8b45b0f26782WX69");
//        request.setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b");
        try {
            AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
            logger.info(response.getAccessToken());
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
//        if(response.isSuccess()){
//            logger.info("调用成功");
//        } else {
//            logger.info("调用失败");
//        }
    }
}
